package com.ruoyi.stock2.es;

import cn.hutool.core.util.HashUtil;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

//文本生成simHshcode
//属于文本指纹匹配
public class SimHashUtil {


    private static int  hashbits =  32 ;

    public static String simHashCode(String text){


        String words[] = text.replaceAll("null,","").split(",");

        Map<String, Integer> keyMap = new HashMap<>();
        for (int i = 0 ; i < words.length; i++) {
            String key = words[i];
            if (keyMap.get(key)!=null) {
                keyMap.put(key, keyMap.get(key) + 1);
            } else {
                keyMap.put(key, 1);
            }
        }

        Map<Integer, Integer> hashMap = new HashMap<>();
        Iterator<Map.Entry<String, Integer>> it = keyMap.entrySet().iterator();
        while(it.hasNext()){

            Map.Entry<String, Integer> entry=it.next();
            String key = entry.getKey();
            Integer value = entry.getValue();

            String binary_str = "";

            if(hashbits == 64){
                binary_str = hexString2binaryString(MD5Encode(key, "utf-8").substring(0,16));

            }else  if(hashbits == 128){
                binary_str = hexString2binaryString(MD5Encode(key, "utf-8"));

            }else  if(hashbits == 32){
                binary_str = Long.toString(HashUtil.cityHash32(key.getBytes()), 2);

            }


            StringBuffer stringBuffer = new StringBuffer(binary_str);

            for(int i=binary_str.length(); i<hashbits; i++){
                stringBuffer.append("0");
            }

            for (int i = 0; i < hashbits; i++) {

                char v1 = stringBuffer.charAt(i);

                Integer v2;

                if (v1 > '0') {
                    v2 = 1 * value;
                } else {
                    v2 = value * (-1);
                }

                if (hashMap.get(i)!=null) {
                    hashMap.put(i, hashMap.get(i) + v2);
                } else {
                    hashMap.put(i, v2);
                }
            }


        }

        StringBuffer stringBuffer = new StringBuffer();

        for (int i = 0; i < hashbits; i++) {
            int v1 = hashMap.get(i);

            if (v1 > 0) {
                hashMap.put(i, 1);
            } else {
                hashMap.put(i, 0);
            }
            stringBuffer.append(hashMap.get(i));
        }

        return stringBuffer.toString();
    }

    private static void getDistance(String hash1, String hash2){
        int distance = 0;
        for (int i = 0; i < hashbits; i++) {
            if (!String.valueOf(hash1.charAt(i)).equals(String.valueOf(hash2.charAt(i))) ) {
                distance = distance + 1;
            }
        }
        System.out.println(distance);
    }

    private static String hexString2binaryString(String hexString) {
        StringBuffer bString = new StringBuffer();
        for (int i = 0; i < hexString.length(); i++) {
            bString.append(myMap.get(hexString.charAt(i)));
        }
        return bString.toString();
    }

    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++){
            resultSb.append(byteToHexString(b[i]));
        }
        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0) {
            n += 256;
        }
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    private static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname)) {
                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
            } else {
                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
            }
        } catch (Exception exception) {
        }
        return resultString;
    }

    private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };

    private static final Map<Character, String> myMap = new HashMap<Character, String>(22);

    static
    {

        myMap.put('0', "0000");
        myMap.put('1', "0001");
        myMap.put('2', "0010");
        myMap.put('3', "0011");
        myMap.put('4', "0100");

        myMap.put('5', "0101");
        myMap.put('6', "0110");
        myMap.put('7', "0111");
        myMap.put('8', "1000");
        myMap.put('9', "1001");

        myMap.put('a', "1010");
        myMap.put('b', "1011");
        myMap.put('c', "1100");
        myMap.put('d', "1101");
        myMap.put('e', "1110");

        myMap.put('f', "1111");
        myMap.put('A', "1010");
        myMap.put('B', "1011");
        myMap.put('C', "1100");
        myMap.put('D', "1101");

        myMap.put('E', "1110");
        myMap.put('F', "1111");
    }



}
